<?php

namespace app\queue;

use app\exception\BusinessException;
use app\helpers\RedisLock;
use app\model\Notify;
use app\model\Orders;
use app\model\ShopsPayment;
use app\service\shopify\action\graph\OrderGraph;
use app\trait\ShopifyTrait;
use Http\Discovery\Exception\NotFoundException;
use think\helper\Arr;
use think\queue\Job;
use think\Request;

class CreateDraftOrderQueue
{
    use ShopifyTrait;
    const QUEUE_NAME = 'CreateDraftOrderQueue';
    public function fire(Job $job, $data)
    {

        // 获取当前尝试次数
        $attempts = $job->attempts();
        $order = Orders::findOrEmpty($data);
        // 业务处理逻辑
        $log = null;
        try {
            echo "开始处理任务第{$attempts}, 创建草稿订单:{$data} ".date('Y-m-d H:i:s')."\n";
            if($order->isEmpty()) throw new NotFoundException("订单不存在");
            $input = $this->formatDraftInputByOrder($order);
            $graph = new OrderGraph($order->shop_id, true);
            $isCreated = true;
            if($order->draft_id){
                $isCreated = false;
                $draftResult = $graph->update_draft_order($order->draft_id,$input);
            }else{
                $draftResult = $graph->create_draft_order($input);
            }
           $log =  Notify::saveParams($order->id, ['draft_params' => $input, 'response' => $draftResult], $isCreated ?Notify::TYPE_CREATE_DRAFT : Notify::TYPE_MODIFY_DRAFT);//创建草稿订单
            $key = $isCreated ? "draftOrderCreate" : "draftOrderUpdate";
            $this->saveDraftResult($order, $draftResult,$key);
            $userErrors = Arr::get($draftResult, 'data.'.$key.'.userErrors', []);
            if($userErrors){
                $messages = implode(',',array_column($userErrors,'message'));
                throw new BusinessException($messages);
            }

            // 任务执行成功
            $job->delete();
            echo "任务处理完成\n";

        }catch (NotFoundException $e){
            $job->delete();
            echo "订单{$data} 找不到，任务结束\n";
        }
        catch (\Exception $e) {

            if($log){
                $params = $log->params;
                $params['error'] = [
                    "message"=>$e->getMessage(),
                    "trace"=>$e->getTrace()
                ];
                $log->params = $params;
                $log->save();
            }

            if($attempts <= 2){
                // 指数退避策略：重试延迟时间逐渐增加（2,4,8秒）
                $delay = pow(2, $attempts);
                echo "任务处理失败，第 {$attempts} 次重试，延迟 {$delay} 秒\n";
                $job->release($delay);
            } else {
                $job->delete();
                echo "任务处理失败，已超过最大尝试次数(3次)\n";
                // 可以记录到日志或数据库，或调用failed方法
            }
        }
    }

    //保存错误信息
    public function failed($data,$e){
        $order = Orders::findOrEmpty($data);
        if(!$order->isEmpty()){
            Orders::saveExceptionMessage($order,$e->getMessage());
        }
    }

    protected function formatDraftInputByOrder(Orders $order): array
    {
        $shipping_address = $order->shippingAddress;
        $billing_address = $order->billingAddress;
        $lineItems = $order->items()->select()->toArray();
        $currencyCode = $order->present_currency;
        $lines = $this->formatDraftItems($lineItems,$currencyCode);
        $tags = [];
        if($order->trade_no) $tags[] = $order->trade_no;
        if($order->paypal_method == Orders::PAYPAL_METHOD_GOOGLE) $tags[] = "GooglePay";
        if($order->paypal_method == Orders::PAYPAL_METHOD_APPLE) $tags[] = "ApplePay";
        $tag = $order->pay_method == ShopsPayment::PAY_METHOD_PAYPAL ? "PP" :'Card';
        $tags[]= $tag;
        $input = [
            "customAttributes" => [
                ['key' => "ip", 'value' => $order->ip],
                ['key' => "cid", 'value' => $order->checkout_id],
            ],
            'discountCodes' => [],
            "presentmentCurrencyCode" => $currencyCode,
            "tags" => $tags,
            "lineItems" => $lines
        ];
        if ($email = $order->email) $input['email'] = $email;

        if ($order->shipping_price_present > 0) {
            $input['shippingLine'] = [
                "title" => $order->shipping_name,
                "price" => $order->shipping_price_present
            ];
        }
        if (!$shipping_address->isEmpty()) {
            $input['shippingAddress'] = [
                "address1" => $shipping_address->address1,
                "city" => $shipping_address->city,
                "province" => $shipping_address->province,
                "country" => $shipping_address->country,
                "zip" => $shipping_address->zip,
                'firstName' => $shipping_address->first_name,
                'lastName' => $shipping_address->last_name,
            ];
            if ($address2 = $shipping_address->address2) {
                $input['shippingAddress']['address2'] = $address2;
            }
            if ($phone = $shipping_address->phone) {
                $input['shippingAddress']['phone'] = $phone;
                $input['phone'] = $phone;
            }
        }

        if (!$billing_address->isEmpty()) {
            $input['billingAddress'] = [
                "address1" => $billing_address->address1,
                "city" => $billing_address->city,
                "province" => $billing_address->province,
                "country" => $billing_address->country,
                "zip" => $billing_address->zip,
                'firstName' => $billing_address->first_name,
                'lastName' => $billing_address->last_name,
            ];
            if ($address2 = $billing_address->address2) {
                $input['billingAddress']['address2'] = $address2;
            }
        }
        return $input;
    }

}